<?php

namespace App\Http\Controllers\Live;

use App\Http\Controllers\Controller;
use App\Models\Live\LiveGroupModel;
use App\Models\Shop;
use App\Models\ShopHost;
use App\Models\ShopPointsChargeLog;
use App\Models\ShopPointsReceiveLog;
use App\Models\ShopPointsSendLog;
use App\Models\TencentAPIModel;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use MongoDB\Client;

use function MongoDB\object;

class ShopController extends Controller
{
    const ALLENAPI_PREFIX="allenapi_";
    public function __construct(){

    }
    public function getRoomInfo(Request $request){
        $room_id=$request['room_id']??null;
        $data=[
            "title"=>"*",
            "status"=>"*",
            "begin"=>"*",
            "end"=>"*",
            "duration"=>"*"
        ];
        if(!empty($room_id)&&$room_id!='all'){
            $res=DB::connection("shop")->table("live_room")->where('id',$room_id)->first(['theme','live_start_time','live_end_time','status','run_time']);
            Log::debug('res='.$room_id.'/'.json_encode($res));
            if(!empty($res)){
                $data['title']=$res->theme;
                $data['status']=$res->status==2?'直播中':($res->status==3?'已结束':'预约中');
                $data['begin']=empty($res->live_start_time)?'NULL':date('Y-m-d h:i:s',$res->live_start_time);
                $data['end']=empty($res->live_end_time)?'NULL':date('Y-m-d h:i:s',$res->live_end_time);
                $data['duration']=empty($res->duration)?$this->calcDuration($res->live_start_time,$res->live_end_time):gmdate('H小时i分钟s秒',$res->duration);
            }
        }
        return $data;
    }
    private function calcDuration($t1,$t2){
        if(!empty($t1)&&!empty($t2)){
            return gmdate('H小时i分钟s秒',$t2-$t1);
        }
        return null;
    }
    public function getLiveDataScreen(Request $request){
        $name=$request['name']??null;
        $room_id=$request['room_id']??null;
        $page=$request['page']??null;
        $pagesize=$request['pagesize']??null;
        return $this->getDataScreen($name,[
            "room_id"=>$room_id,
            "page"=>$page,
            "pagesize"=>$pagesize
        ]);
    }
    public function getLiveRoomChatMsgList(Request $request){
        $room_id=$request['room_id']??null;
        if(is_int($room_id)){
            $result=DB::connection("shop")->table("live_room")->where('id',$room_id)->value('msg_group_id');
            if(!empty($result))
            $room_id=$result;
        }
        $tencent=new TencentAPIModel();
        $msgList=$tencent->getGroupRoomMsgList($room_id);
        return $msgList;
    }
    private function getDataScreen($name,$params){
        $expire_minute=0.5;
        $r_key="api.shop.datascreen";
        $data=null;
        $room_id=$params['room_id']??null;
        if(empty($room_id))
        return null;
        $r_key.=".room_{$room_id}";
        $last_refresh_time=Redis::HGET($r_key,"last_refresh_time");
        $now_time=time();
        $refresh=false;
        if($name=='top_n_product'){
            $refresh=true;
        }else{
            $refresh=true;
            if(empty($last_refresh_time)){
                $last_refresh_time=$now_time;
                $expires_time=$now_time+($expire_minute*60);
                Redis::HSET($r_key,'expires_time',$expires_time);
                Redis::HSET($r_key,'last_refresh_time',$last_refresh_time);
                $refresh=true;
            }else{
                $expires_time=Redis::HGET($r_key,"expires_time");
                if(empty($expires_time)||$now_time>intval($expires_time)){
                    $last_refresh_time=$now_time;
                    $expires_time=$now_time+($expire_minute*60);
                    Redis::HSET($r_key,'expires_time',$expires_time);
                    Redis::HSET($r_key,'last_refresh_time',$last_refresh_time);
                    $refresh=true;
                }
            }
        }
        if(!empty($name)&&!empty($room_id))
        switch($name){
            case 'last_refresh_time':{
                $data=date('Y-m-d H:i:s',$last_refresh_time);
                break;
            }
            case 'total_deal_success_money':{//总成交金额
                $args=[1];
                $sql="SELECT sum(order_money) as v FROM `order` WHERE pay_status=?";
                if($room_id!=='all'){
                    $sql.=" and room_id=?";
                    $args[]=$room_id;
                }
                if($refresh||empty(Redis::HGET($r_key,$name))){
                $res=DB::connection("shop")->selectOne($sql,$args);
                $data=!empty($res)?$res->v??0:0;
                Redis::HSET($r_key,$name,$data);
                }else{
                $data=Redis::HGET($r_key,$name);
                }
                break;
            }
            case 'total_deal_success_product':{//总成交商品
                $args=[1];
                $sql="SELECT count(order_id) as v FROM `order` WHERE pay_status=?";
                if($room_id!=='all'){
                    $sql.=" and room_id=?";
                    $args[]=$room_id;
                }
                if($refresh||empty(Redis::HGET($r_key,$name))){
                $res=DB::connection("shop")->selectOne($sql,$args);
                $data=!empty($res)?$res->v??0:0;
                Redis::HSET($r_key,$name,$data);
                }else{
                $data=Redis::HGET($r_key,$name);
                }
                break;
            }
            case 'total_deal_success_buyer':{//总成交买家
                $args=[1];
                $sql="SELECT count(DISTINCT member_id) as v FROM `order` WHERE pay_status=?";
                if($room_id!=='all'){
                    $sql.=" and room_id=?";
                    $args[]=$room_id;
                }
                if($refresh||empty(Redis::HGET($r_key,$name))){
                $res=DB::connection("shop")->selectOne($sql,$args);
                $data=!empty($res)?$res->v??0:0;
                Redis::HSET($r_key,$name,$data);
                }else{
                $data=Redis::HGET($r_key,$name);
                }
                break;
            }
            case 'total_product_visitor_size':{//商品总浏览量  
            }
            case 'total_product_click_size':{//商品总点击量        
                $args=[];
                $sql="SELECT count(member_id) as v FROM `live_goods_view`";
                if($room_id!=='all'){
                    $sql.=" WHERE room_id=?";
                    $args[]=$room_id;
                }
                $sql.=" group by member_id";
                if($refresh||empty(Redis::HGET($r_key,$name))){
                $res=DB::connection("shop")->selectOne($sql,$args);
                $data=!empty($res)?$res->v??0:0;
                Redis::HSET($r_key,$name,$data);
                }else{
                $data=Redis::HGET($r_key,$name);
                }
                break;
            }
            case 'total_success_deal_translate_rate':{//总商品成交转化率
                $args_total_member=[1];
                $sql_total_member="SELECT count(member_id) as v FROM `order` WHERE pay_status=?";
                if($room_id!=='all'){
                    $sql_total_member.=" and room_id=?";
                    $args_total_member[]=$room_id;
                }
                $sql_total_member.=" group by member_id";
                $args=[1];
                $sql="SELECT count(order_id) as v FROM `order` WHERE pay_status=?";
                if($room_id!=='all'){
                    $sql.=" AND room_id=?";
                    $args[]=$room_id;
                }
                if($refresh||empty(Redis::HGET($r_key,$name))){
                 $res_ok=DB::connection("shop")->selectOne($sql_total_member,$args_total_member);
                 $res_ok=!empty($res_ok)?$res_ok->v??0:0;
                 $res_all=DB::connection("shop")->selectOne($sql,$args);
                 $res_all=!empty($res_all)?$res_all->v??0:0;
                 if(!empty($res_all)&&!empty($res_ok)){
                    //$data=[$res_ok,$res_all,bcdiv($res_ok,$res_all,2)];
                    $data=bcdiv($res_ok,$res_all,2);
                 }else{
                    $data=null;   
                 }
                 Redis::HSET($r_key,$name,$data);
                }else{
                 $data=Redis::HGET($r_key,$name);
                }
                break;
            }
            case 'liveroom_hot_count':{//直播间热度
                $refresh=true;
                $args=[];
                $sql="SELECT sum(preview_num) as v FROM `live_room`";
                if($room_id!=='all'){
                    $sql.=" WHERE id=?";
                    $args[]=$room_id;
                }
                if($refresh||empty(Redis::HGET($r_key,$name))){
                $res=DB::connection("shop")->selectOne($sql,$args);
                $data=!empty($res)?$res->v??0:0;
                Redis::HSET($r_key,$name,$data);
                }else{
                $data=Redis::HGET($r_key,$name);
                }
                break;
            }
            case 'liveroom_comment_member_count':{//直播评论人数
                $match=[
                        'oprate_type'=>'comment'
                ];
                if($room_id!=='all'){
                    $match['room_id']=$room_id;
                }
                $group=[
                    '_id'=>'$member_id',
                ];
                $arr=[];
                $arr[]=['$match'=>(object)$match];
                $arr[]=['$group'=>(object)$group];
                $arr[]=['$count'=>'cnt'];
                if($refresh||empty(Redis::HGET($r_key,$name))){
                 $mongo=new Client(env("MONGO_URI"));
                 $db=$mongo->selectDatabase("shop_live");
                 $collection=$db->selectCollection("event_list");
                 $aaa=$collection->aggregate($arr)->toArray();
                 if(!empty($aaa))
                 $data=$aaa[0]->cnt;
                 else
                 $data=0;
                 Redis::HSET($r_key,$name,$data);
                }else{
                 $data=Redis::HGET($r_key,$name);
                }
                break;
            }
            case 'liveroom_comment_count':{//直播评论数
                $match=[
                        'oprate_type'=>'comment'
                ];
                if($room_id!=='all'){
                    $match['room_id']=$room_id;
                }
                $group=[
                    '_id'=>'$member_id',
                ];
                $arr=[];
                $arr[]=['$match'=>(object)$match];
                $arr[]=['$count'=>'cnt'];
                if($refresh||empty(Redis::HGET($r_key,$name))){
                 $mongo=new Client(env("MONGO_URI"));
                 $db=$mongo->selectDatabase("shop_live");
                 $collection=$db->selectCollection("event_list");
                 $aaa=$collection->aggregate($arr)->toArray();
                 if(!empty($aaa))
                 $data=$aaa[0]->cnt;
                 else
                 $data=0;
                 Redis::HSET($r_key,$name,$data);
                }else{
                 $data=Redis::HGET($r_key,$name);
                }
                break;
            }
            case 'liveroom_share_member_count':{//直播分享人数
                $match=[
                        'oprate_type'=>'share'
                ];
                if($room_id!=='all'){
                    $match['room_id']=$room_id;
                }
                $group=[
                    '_id'=>'$member_id',
                ];
                $arr=[];
                $arr[]=['$match'=>(object)$match];
                $arr[]=['$group'=>(object)$group];
                $arr[]=['$count'=>'cnt'];
                if($refresh||empty(Redis::HGET($r_key,$name))){
                 $mongo=new Client(env("MONGO_URI"));
                 $db=$mongo->selectDatabase("shop_live");
                 $collection=$db->selectCollection("event_list");
                 $aaa=$collection->aggregate($arr)->toArray();
                 if(!empty($aaa))
                 $data=$aaa[0]->cnt;
                 else
                 $data=0;
                 Redis::HSET($r_key,$name,$data);
                }else{
                 $data=Redis::HGET($r_key,$name);
                }
                break;
            }
            case 'liveroom_share_count':{//直播分享人次
                $match=[
                        'oprate_type'=>'share'
                ];
                if($room_id!=='all'){
                    $match['room_id']=$room_id;
                }
                $group=[
                    '_id'=>'$member_id',
                ];
                $arr=[];
                $arr[]=['$match'=>(object)$match];
                $arr[]=['$count'=>'cnt'];
                if($refresh||empty(Redis::HGET($r_key,$name))){
                 $mongo=new Client(env("MONGO_URI"));
                 $db=$mongo->selectDatabase("shop_live");
                 $collection=$db->selectCollection("event_list");
                 $aaa=$collection->aggregate($arr)->toArray();
                 if(!empty($aaa))
                 $data=$aaa[0]->cnt;
                 else
                 $data=0;
                 Redis::HSET($r_key,$name,$data);
                }else{
                 $data=Redis::HGET($r_key,$name);
                }
                break;
            }
            case 'total_audience_view_number':{//直播观看人次
            }
            case 'total_audience_view_number_max':{//直播观看峰值人次
                $match=[
                        'oprate_type'=>'join'
                ];
                if($room_id!=='all'){
                    $match['room_id']=$room_id;
                }
                $group=[
                    '_id'=>'$member_id',
                ];
                $arr=[];
                $arr[]=['$match'=>(object)$match];
                $arr[]=['$count'=>'cnt'];
                if($refresh||empty(Redis::HGET($r_key,$name))){
                 $mongo=new Client(env("MONGO_URI"));
                 $db=$mongo->selectDatabase("shop_live");
                 $collection=$db->selectCollection("event_list");
                 $aaa=$collection->aggregate($arr)->toArray();
                 if(!empty($aaa))
                 $data=$aaa[0]->cnt;
                 else
                 $data=0;
                 Redis::HSET($r_key,$name,$data);
                }else{
                 $data=Redis::HGET($r_key,$name);
                }
                break;
            }
            case 'total_audience_count':{//直播观看人数
            }
            case 'total_audience_count_max':{//直播观看峰值人数
                $match=[
                        'oprate_type'=>'join'
                ];
                if($room_id!=='all'){
                    $match['room_id']=$room_id;
                }
                $group=[
                    '_id'=>'$member_id',
                ];
                $arr=[];
                $arr[]=['$match'=>(object)$match];
                $arr[]=['$group'=>(object)$group];
                $arr[]=['$count'=>'cnt'];
                if($refresh||empty(Redis::HGET($r_key,$name))){
                 $mongo=new Client(env("MONGO_URI"));
                 $db=$mongo->selectDatabase("shop_live");
                 $collection=$db->selectCollection("event_list");
                 $aaa=$collection->aggregate($arr)->toArray();
                 if(!empty($aaa))
                 $data=$aaa[0]->cnt;
                 else
                 $data=0;
                 Redis::HSET($r_key,$name,$data);
                }else{
                 $data=Redis::HGET($r_key,$name);
                }
                break;
            }
            case 'total_audience_all':{//总观众

            }
            case 'total_audience_current':{//当前在线总观众
                if($refresh||empty(Redis::HGET($r_key,$name))){
                // $domainName="pull.51zhideai.com";
                // $appName="zdaishop";
                // $streamName="5_1760344119";
                // $beginTime="2025-10-13T00:00:00Z";
                // $endTime="2025-10-13T23:59:59Z";
                // $body=AliCloudManagerController::getLiveRoomState($domainName,$appName,$streamName,$beginTime,$endTime);
                $data=0;
                $group_ids=[];
                if($room_id!=='all'){
                    $v=DB::connection('shop')->table('live_room')->where('id',$room_id)->where('status',2)->whereNotNull('msg_group_id')->where('msg_group_id','<>','')->value('msg_group_id');
                    if(!empty($v))
                    $group_ids[]=$v;
                }else{
                    $group_ids=DB::connection('shop')->table('live_room')->where('status',2)->whereNotNull('msg_group_id')->where('msg_group_id','<>','')->pluck('msg_group_id');
                }
                if(!empty($group_ids)){
                    foreach($group_ids as $v){
                        $val=LiveGroupModel::getGroupOnlineUserCount($v);
                        if(!empty($val)){
                            $num=Redis::connection("noprefix")->GET(sprintf("live_room_members_offline_num:%s",$room_id));
                            $num=empty($num)?0:$num;
                            $data+=$val+$num;
                        }
                    }
                }
                Redis::HSET($r_key,$name,$data);
                }else{
                $data=Redis::HGET($r_key,$name);
                }
                break;
            }
            case 'average_price':{//成交均价
                $args_total_ordermoney=[1];
                $sql_total_ordermoney="SELECT sum(order_money) as v FROM `order` WHERE pay_status=?";
                if($room_id!=='all'){
                    $sql_total_ordermoney.=" and room_id=?";
                    $args_total_ordermoney[]=$room_id;
                }
                $args_total_ordermember=[1];
                $sql_total_ordermember="SELECT count(member_id) as v FROM `order` WHERE pay_status=?";
                if($room_id!=='all'){
                    $sql_total_ordermember.=" and room_id=?";
                    $args_total_ordermember[]=$room_id;
                }
                $sql_total_ordermember.=" GROUP BY member_id";
                $avg_sql="SELECT avg(order_money) as v FROM `order` WHERE pay_status=?";
                $avg_params=[1];
                if($room_id!=='all'){
                    $avg_sql.=" and room_id=?";
                    $avg_params[]=$room_id;
                }
                if($refresh||empty(Redis::HGET($r_key,$name))){
                // $res_total_ordermoney=DB::connection("shop")->selectOne($sql_total_ordermoney,$args_total_ordermoney);
                // $res_total_ordermember=DB::connection("shop")->selectOne($sql_total_ordermember,$args_total_ordermember);
                // $data_total_ordermoney=!empty($res_total_ordermoney)?$res_total_ordermoney->v??null:null;
                // $data_total_ordermember=!empty($res_total_ordermember)?$res_total_ordermember->v??null:null;
                // if(!empty($data_total_ordermoney)&&!empty($data_total_ordermember))
                // $data=bcdiv($data_total_ordermoney,$data_total_ordermember,2);
                // else

                $res=DB::connection("shop")->selectOne($avg_sql,$avg_params);
                $data=!empty($res)?$res->v??0:0;
                Redis::HSET($r_key,$name,$data);
                }else{
                $data=Redis::HGET($r_key,$name);
                }
                break;
            }
            case 'not_pay_size':{//未付款订单数
                $args=[0];
                $sql="SELECT count(order_id) as v FROM `order` WHERE pay_status=?";
                if($room_id!=='all'){
                    $sql.=" and room_id=?";
                    $args[]=$room_id;
                }
                if($refresh||empty(Redis::HGET($r_key,$name))){
                $res=DB::connection("shop")->selectOne($sql,$args);
                $data=!empty($res)?$res->v??0:0;
                Redis::HSET($r_key,$name,$data);
                }else{
                $data=Redis::HGET($r_key,$name);
                }
                break;
            }
            case 'average_audience_duration':{//观众在线平均时长
                $args=[];
                if($refresh||empty(Redis::HGET($r_key,$name))){
                $sql="SELECT avg(view_time) as v FROM live_member_join";
                if($room_id!=='all'){
                    $sql.=" where room_id=?";
                    $args[]=$room_id;
                }
                $res=DB::connection("shop")->selectOne($sql,$args);
                $data=!empty($res)?$res->v??0:0;
                Redis::HSET($r_key,$name,$data);
                }else{
                $data=Redis::HGET($r_key,$name);
                }
                $data=gmdate('H:i:s',intval($data));
                break;
            }
            case 'order_newold_buyer':{//新老客户订单数量
                $args=[1];
                $sql="SELECT member_id FROM `order` WHERE pay_status=? ";
                if($room_id!=='all'){
                    $sql.=" and room_id=?";
                    $args[]=$room_id;
                }
                $sql="SELECT member_id,COUNT(member_id) as v from `order` where member_id in ({$sql}) group by member_id";
                $sql="SELECT member_id,case when v=1 then 'newer' else 'older' end as newold from ({$sql}) as t1";
                $sql="SELECT newold,count(newold) as v FROM ({$sql}) as t2 group by newold";
                if($refresh||empty(Redis::HGET($r_key,$name))){
                $res=DB::connection("shop")->select($sql,$args);
                $data=[
                    "newer"=>0,
                    "older"=>0
                ];
                if(!empty($res)){
                    foreach($res as $v){
                        $data[$v->newold]=$v->v;
                    }
                }
                Redis::HSET($r_key,$name,json_encode($data));
                }else{
                $data=Redis::HGET($r_key,$name);
                if(!empty($data))
                $data=json_decode($data);
                }
                break;
            }
            // case 'order_new_buyer':{//订单新客数量
            //     $args=[1];
            //     $sql="SELECT member_id FROM `order` WHERE pay_status=? ";
            //     if($room_id!=='all'){
            //         $sql.=" and room_id=?";
            //         $args[]=$room_id;
            //     }
            //     $sql.=" group by member_id having count(order_id) = 1";
            //     $sql="SELECT COUNT(t1.member_id) as v from ({$sql}) t1";
            //     if($refresh||empty(Redis::HGET($r_key,$name))){
            //     $res=DB::connection("shop")->selectOne($sql,$args);
            //     $data=!empty($res)?$res->v??0:0;
            //     Redis::HSET($r_key,$name,$data);
            //     }else{
            //     $data=Redis::HGET($r_key,$name);
            //     }
            //     break;
            // }
            // case 'order_older_buyer':{//订单老客数量
            //     $args=[1];
            //     $sql="SELECT member_id FROM `order` WHERE pay_status=? ";
            //     if($room_id!=='all'){
            //         $sql.=" and room_id=?";
            //         $args[]=$room_id;
            //     }
            //     $sql.=" group by member_id having count(order_id)>1";
            //     $sql="SELECT COUNT(t1.member_id) as v from ({$sql}) t1";
            //     if($refresh||empty(Redis::HGET($r_key,$name))){
            //     $res=DB::connection("shop")->selectOne($sql,$args);
            //     $data=!empty($res)?$res->v??0:0;
            //     Redis::HSET($r_key,$name,$data);
            //     }else{
            //     $data=Redis::HGET($r_key,$name);
            //     }
            //     break;
            // }
            case 'invite_top_n':{
                $img_server="https://zhideai.oss-cn-chengdu.aliyuncs.com";
                $args=[];
                $n=10;
                $sql="SELECT i.invite_member_id,m.nickname,m.headimg,count(i.member_id) AS v FROM live_invite i JOIN member m ON i.invite_member_id = m.member_id";
                if($room_id!=='all'){
                    $sql.=" and i.room_id=?";
                    $args[]=$room_id;
                }
                $sql.=" GROUP BY i.invite_member_id ORDER BY v DESC LIMIT 10";
                if($refresh||empty(Redis::HGET($r_key,$name))){
                $res=DB::connection("shop")->select($sql,$args);
                if(!empty($res)){
                    $data=[];
                 foreach($res as $v){
                    $data[]=[
                        "id"=>$v->invite_member_id,
                        "name"=>DB::connection("shop")->table("member")->where('member_id',$v->invite_member_id)->value("nickname"),
                        "img"=>$img_server.(substr($v->headimg,0,1)=='/'?$v->headimg:'/'.$v->headimg),
                        "v"=>$v->v,
                    ];
                 }
                }
                Redis::HSET($r_key,$name,json_encode($data));
                }else{
                $data=Redis::HGET($r_key,$name);
                $data=json_decode($data);
                }
                break;
            }
            case 'top_n_area':{
                $args=[];
                $n=10;
                $sql_0="(SELECT province_id,count(order_id) AS all_size,0 as pay_size FROM `order` WHERE 1=1";
                $sql_1="(SELECT province_id,0 as all_size,count(order_id) AS pay_size FROM `order` WHERE pay_status=1";
                if($room_id!=='all'){
                    $sql_0.=" and room_id=?";
                    $args[]=$room_id;
                }
                if($room_id!=='all'){
                    $sql_1.=" and room_id=?";
                    $args[]=$room_id;
                }
                $sql_0.=' GROUP BY province_id)';
                $sql_1.=' GROUP BY province_id)';
                $sql="SELECT t.province_id,a.`name`,SUM(t.all_size) as all_size,sum(t.pay_size) as pay_size FROM (";
                $sql.=$sql_0." UNION ALL " . $sql_1;
                $sql.=") t JOIN area a ON a.id=t.province_id group by t.province_id";
                $sql="SELECT `name`,all_size,pay_size,ROUND(pay_size/all_size,2)*100 as v FROM ({$sql}) tmp ORDER BY all_size DESC,pay_size DESC,v DESC LIMIT 0,10";
                if($refresh||empty(Redis::HGET($r_key,$name))){
                $data=DB::connection("shop")->select($sql,$args);
                Redis::HSET($r_key,$name,json_encode($data));
                }else{
                $data=Redis::HGET($r_key,$name);
                $data=json_decode($data);
                }
                break;
            }
            case 'top_n_product':{
                $total_product_size=0;
                $args=[];
                $page=$params['page']??1;
                $pagesize=$params['pagesize']??8;
                $offset=($page-1)*$pagesize;
                $sql_0="(SELECT g.goods_name,g.price,g.live_status,count(o.member_id) as all_size,0 as pay_size from `order` o JOIN order_goods og on og.order_id=o.order_id JOIN goods g ON g.goods_id = og.goods_id where 1=1";
                $sql_1="(SELECT g.goods_name,g.price,g.live_status,0 as all_size,count(o.member_id) as pay_size from `order` o JOIN order_goods og on og.order_id=o.order_id JOIN goods g ON g.goods_id = og.goods_id where o.pay_status=1";
                if($room_id!=='all'){
                    $sql_0.=" and o.room_id=?";
                    $args[]=$room_id;
                }
                if($room_id!=='all'){
                    $sql_1.=" and o.room_id=?";
                    $args[]=$room_id;
                }
                $sql_0.=' GROUP BY g.goods_name,g.price,g.live_status)';
                $sql_1.=' GROUP BY g.goods_name,g.price,g.live_status)';
                $sql="SELECT goods_name,price,live_status,sum(all_size) as all_size,sum(pay_size) as pay_size FROM (";
                $sql.=$sql_0." UNION ALL " . $sql_1;
                $sql.=") t  GROUP BY goods_name,price,live_status ";
                $total_sql="SELECT COUNT(goods_name) as v FROM ({$sql}) tmp";
                $sql.=" ORDER BY all_size DESC,pay_size DESC limit {$offset},{$pagesize}";
                $sql="SELECT *,ROUND(pay_size/all_size,2)*100 as v FROM ({$sql}) tmp";
                if($refresh||empty(Redis::HGET($r_key,$name))){
                $data=DB::connection("shop")->select($sql,$args);
                $total_product_size=DB::connection("shop")->selectOne($total_sql,$args);
                $total_product_size=$total_product_size->v;
                Redis::HSET($r_key,$name,json_encode($data));
                Redis::HSET($r_key,$name."_total",$total_product_size);
                }else{
                $data=Redis::HGET($r_key,$name);
                $total_product_size=Redis::HGET($r_key,$name."_total");
                $data=json_decode($data);
                }
                $data=[
                    "list"=>$data,
                    "totalsize"=>$total_product_size
                ];
                break;
            }
            default:{
                break;
            }
        }
        return response()->json($data);
    }
    public static function getLiveRooms($refresh=false){
            $cache_key=self::ALLENAPI_PREFIX.'room_list';
            $rooms=[];
            if(!Redis::EXISTS($cache_key)||$refresh){
                $roomList=DB::connection('shop')->table('live_room')->get();
                foreach($roomList as $v){
                    $rooms['room_'.$v->id]=(object)[//强转object类型 上下文均使用对象方法获取房间属性 需统一
                        'title'=>$v->theme,
                        'shop_id'=>$v->site_id,
                        'host_id'=>$v->member_id,
                        'group_id'=>$v->msg_group_id
                    ];
                }
                Redis::SET($cache_key,json_encode($rooms));
            }else{
                $rooms=json_decode(Redis::GET($cache_key));
            }
            return (object)$rooms;//强转object类型 上下文均使用对象方法获取房间属性 需统一
    }
    private function checkSession($key1,$key2=null){
        $ssid=$_COOKIE['PHPSESSID']??null;
        if(empty($ssid)){
                return response()->json([
                    'null ssid'
                ]);
        }
        $ssvalue=Redis::connection("session123")->GET($ssid);
        if(empty($ssvalue)){
                return response()->json([
                    'null ssvalue'
                ]);
        }
        $data=unserialize(unserialize($ssvalue));
        if(empty($key2)){
         $id=$data[$key1]??null;
        }else{
         $id=$data[$key1][$key2]??null;
        }
        if(empty($id)){
                return response()->json([
                    'null id'
                ]);
        }
        return $id;
    }
    //刷新房间列表
    public function refreshRoomList(Request $request){
        $user=$request['user']??null;
        if(!empty($user)&&$user=='admin'){
            $rooms=self::getLiveRooms(true);
            return response()->json([
                'rooms'=>$rooms
            ]);
        }
        return null;
    }
    //充值积分
    public function setPoints(Request $request){
        $jober=$request['job_runner']??null;//如果请求是任务调度器则存在该值
        $user_info=[];
        $admin_info=$this->checkSession('admin','user_info');
        $shop_info=$this->checkSession('shop','user_info');
        if(empty($jober)){
            if($admin_info instanceof JsonResponse && $shop_info instanceof JsonResponse)
            return $shop_info;
            if(!($admin_info instanceof JsonResponse))
            $user_info=[
                "uid"=>$admin_info['uid'],
                "username"=>$admin_info['username']
            ];
            if(!($shop_info instanceof JsonResponse))
            $user_info=[
                "uid"=>$shop_info['uid'],
                "username"=>$shop_info['username']
            ];
        }else{//来自退回任务调度器不进行Token验证
            $user_info=[
                "uid"=>0,
                "username"=>'jober'
            ];
        }
        $shop_id=$request['shop_id']??null;
        $host_id=$request['host_id']??null;
        $changeObj=$request['change']??null;
        $change_name="";
        $change_value="";
        $change_msg="";
        if(!empty($changeObj)){
            $change_name=$changeObj['name']??null;
            $change_value=$changeObj['value']??null;
            $change_msg=$changeObj['msg']??null;
        }else{
            return response()->json([
                'code'=>-1,
                'msg'=>'error change obj'
            ]);
        }
        if($change_name!='退回')
        if(Redis::GET(self::ALLENAPI_PREFIX.'points_set_expire_'.$shop_id)){
            return response()->json([
                'code'=>-1,
                'msg'=>'request too much'
            ]);
        }
        if(empty($shop_id)||empty($host_id)){
            return response()->json([
                'code'=>-1,
                'msg'=>'error shop_id or host_id'
            ]);
        }
        if($change_name!='退回')
        Redis::SET(self::ALLENAPI_PREFIX.'points_set_expire_'.$shop_id,1,'EX',10);
        $oprate_ip=$request->getClientIp();
        $oprater_id=$user_info['uid']??null;
        $oprater_name=$user_info['username']??null;
        $oprate_flag=null;
        $oprate_msg=null;
        switch($change_name){
            case '充值':{
                $oprate_flag='+';
                break;
            }
            case '扣除':{
                $oprate_flag='-';
                break;
            }
            case '退回':{
                $oprate_flag='+';
                break;
            }
            default:{
                return response()->json([
                    'code'=>-1,
                    'msg'=>'error change name'
                ]);
            }
        }
        $oprate_msg="{$oprate_flag}{$change_value}";
        $oprate_value=$change_value;
        DB::beginTransaction();
        try{

        $shop=Shop::newShop([
            'shop_id'=>$shop_id
        ]);
        if(empty($shop)){
                return response()->json([
                    'code'=>-1,
                    'msg'=>'error shop'
                ]);
        }
        $host=ShopHost::newShopHost([
            'shop_id'=>$shop_id,
            'host_id'=>$host_id
        ]);
        if(empty($host)){
                return response()->json([
                    'code'=>-1,
                    'msg'=>'error host'
                ]);
        }
        //直播主持人的积分余额进行调整
        $points=ShopHost::setPoints($host_id,[
            'flag'=>$oprate_flag,
            'value'=>$oprate_value
        ]);
        if($points===null||$points===false){
                return response()->json([
                    'code'=>-1,
                    'msg'=>'error points'
                ]);
        }
        $before_value=$points[0];
        $after_value=$points[1];
        $log=ShopPointsChargeLog::create([
                'shop_id'=>$shop_id,
                'shop_name'=>$shop->origin_name,
                'host_id'=>$host_id,
                'host_name'=>$host->origin_name,
                'host_account'=>$host->origin_account,
                'change_name'=>$change_name,
                'change_msg'=>$change_msg,
                'oprater_id'=>$oprater_id,
                'oprater_name'=>$oprater_name,
                'oprate_ip'=>$oprate_ip,
                'oprate_flag'=>$oprate_flag,
                'oprate_value'=>$oprate_value,
                'oprate_msg'=>$oprate_msg,
                'before_value'=>$before_value,
                'after_value'=>$after_value
            ]
        );
        }catch(Exception $e){
            DB::rollBack();
            Log::debug($e->getTraceAsString());
            return response()->json([
                        'code'=>-1,
                        'msg'=>'throw Exception DB coming rallback'.$e->getMessage()
            ]);
        }
        DB::commit();
        if(!empty($log->id)){
            return response()->json([
                'id'=>$log->id
            ]);
        }else{
            return response()->json([
                'id'=>null
            ]);
        }
        return response()->json([
                    'code'=>-1,
                    'msg'=>'error log'
        ]);
    }
    //积分余额查询
    public function shopPointsBalance(Request $request){
        $admin_id=$this->checkSession('admin','uid');
        $shop_id=$this->checkSession('shop','uid');
        $checker=0;
        if($admin_id instanceof JsonResponse){
            $checker++;
        }
        if($shop_id instanceof JsonResponse){
            $checker++;
        }
        if($checker==2){
            return $shop_id;
        }
        $data=[
            'total'=>0,
            'used'=>0
        ];
        if($request->header('x-requested-with')=='XMLHttpRequest'){
            $site_id=$request['site_id']??null;
            $host_id=$request['host_id']??null;
            $only_total=$request['only_total']??null;
            $where=[

            ];
            if(!empty($site_id)){
                $where[
                    'site_id'
                ]=$site_id;
            }
            if(!empty($host_id)){
                $where[
                    'host_id'
                ]=$host_id;
            }
            if(!empty($only_total)){
            $data['total']=ShopHost::where([
                    'shop_id'=>$site_id,
                    'origin_member_id'=>$host_id,
                ])->sum('points');
            }else{
            $data['total']=ShopHost::where([
                    'shop_id'=>$site_id
                ])->sum('points');
            $data['used']=ShopPointsSendLog::where([
                    'shop_id'=>$site_id
                ])->sum('points')-ShopPointsChargeLog::where([
                    'shop_id'=>$site_id,
                    'change_name'=>'退回'
            ])->sum('oprate_value');
            }
            return $data;
        }else{
            return null;
        }
    }
    //积分余额查询
    public function pointsBalance(Request $request){
        $points=null;
        if($request->header('x-requested-with')=='XMLHttpRequest'){
         $member_id=$request['member_id']??null;
         if(!empty($member_id)){
            $points=ShopHost::getPoints($member_id);
         }
        }
        return response()->json([
            'balance'=>$points
        ]);
    }
    public function pointReceiverSize(Request $request){
        $uid=$this->checkSession('shop','uid');
        if($uid instanceof \Illuminate\Http\JsonResponse){
            return $uid;
        }
        if($request->header('x-requested-with')=='XMLHttpRequest'){
        $activity_id=$request['activity_id']??null;
        $where=[
            'activity_id'=>$activity_id
        ];
        $total=ShopPointsReceiveLog::where($where)->count();
        $data=[
            "title"=>"积分活动参与人数",
            'code'=>0,
            'message'=>'success',
            'data'=>[
                'total'=>$total,
                'uid'=>$uid
            ]
        ];
            return $data;
        }else{
            return null;
        }
    }
    public function pointReceiverList(Request $request){
        $uid=$this->checkSession('shop','uid');
        $activity_id=$request['activity_id']??null;
        $where=[
            'activity_id'=>$activity_id
        ];
        $page=$request['page']??1;
        $limit=$request['page_size']??16;
        $count=ShopPointsReceiveLog::where($where)->count();
        $pagecount=$count<=$limit?1:($count%$limit==0?intval($count/$limit):intval($count/$limit)+1);
        $offset=($page-1)*$limit;
        $list=ShopPointsReceiveLog::with('activity')->where($where)->orderBy('id','desc')->offset($offset)->limit($limit)->get();
        foreach($list as $k=>$v){
            if(is_numeric($v->receive_name)){
                $info=DB::connection("shop")->table("member")->where("member_id",$v->receive_id)->first(['nickname','headimg']);
                $v->receive_name=$info->nickname;
                $v->headimg=$info->headimg;
            }
        }
        $data=[
            "title"=>"积分活动参与列表",
            'code'=>0,
            'message'=>'success',
            'data'=>[
                'count'=>$count,
                'list'=>$list,
                'page_count'=>$pagecount
            ]
        ];
        if($request->header('x-requested-with')=='XMLHttpRequest'){
            return $data;
        }else{
            return null;
        }
    }
    public function sendPointsLogList(Request $request){
        $uid=$this->checkSession('shop','uid');
        $site_id=$request['site_id']??null;
        $room_id=$request['room_id']??null;
        $page=$request['page']??1;
        $limit=$request['page_size']??16;
        $where=[
            'shop_id'=>$site_id
        ];
        if(!empty($room_id)){
            $where['room_id']=$room_id;
        }
        $count=ShopPointsSendLog::where($where)->count();
        $pagecount=$count<=$limit?1:($count%$limit==0?intval($count/$limit):intval($count/$limit)+1);
        $offset=($page-1)*$limit;
        $list=ShopPointsSendLog::select('id','points','amount','point','host_id','room_id','created_at')->withCount('receivers')->where($where)->orderBy('id','desc')->offset($offset)->limit($limit)->get();
        $rooms=[];
        if(!empty($list)){
            $rooms=self::getLiveRooms();
            foreach($list as $k=>$v){
                $host=Redis::GET(ShopHost::REDIS_PREFIX.$v->host_id);
                if(!empty($host)){
                    $host=json_decode($host);
                    $attr='room_'.$v->room_id;
                    $list[$k]['title']=$rooms->$attr->title??null;
                    $list[$k]['sender']=$host->origin_name;
                    $list[$k]['receiver']=$v->receivers_count??null;
                    $list[$k]['points']=$v->points."/".$v->amount;
                    $list[$k]['created_at']=$v->created_at;
                }
            }
        }
        $data=[
            "title"=>"积分派发",
            'code'=>0,
            'message'=>'操作成功',
            'data'=>[
                'count'=>$count,
                'list'=>$list,
                'page_count'=>$pagecount
            ]
        ];
        if($request->header('x-requested-with')=='XMLHttpRequest'){
            return $data;
        }else{
            return null;
        }
    }
    public function chargePointsLogList(Request $request){
        $admin_id=$this->checkSession('admin','uid');
        $shop_id=$this->checkSession('shop','uid');
        $checker=0;
        if($admin_id instanceof JsonResponse){
            $checker++;
        }
        if($shop_id instanceof JsonResponse){
            $checker++;
        }
        if($checker==2){
            return $shop_id;
        }
        $site_id=$request['site_id']??null;
        $site_name=$request['site_name']??null;
        $charge_name=$request['charge_name']??null;
        $page=$request['page']??1;
        $limit=$request['page_size']??16;
        $where=[];
        if(!empty($site_id)){
            $where[]=[
                'shop_id','=',$site_id
            ];
        }
        if(!empty($site_name)){
            $where[]=[
                'shop_name','like',"%{$site_name}%"
            ];
        }
        if(!empty($charge_name)){
            $where[]=[
                'charge_name','=',$charge_name
            ];
        }
        $count=ShopPointsChargeLog::where($where)->count();
        $pagecount=$count<=$limit?1:($count%$limit==0?intval($count/$limit):intval($count/$limit)+1);
        $offset=($page-1)*$limit;
        $list=ShopPointsChargeLog::where($where)->orderBy('id','desc')->offset($offset)->limit($limit)->get();
        $data=[
            "title"=>"积分充值列表",
            'code'=>0,
            'message'=>'操作成功',
            'data'=>[
                'count'=>$count,
                'list'=>$list,
                'page_count'=>$pagecount
            ]
        ];
        if($request->header('x-requested-with')=='XMLHttpRequest'){
            return $data;
        }else{
            return null;
        }
    }
    public static function  shop_decrypt($data, $key = '')
{
    $key = md5(empty ($key) ? 'niucloud' : $key);
    $data = str_replace(array(
        '-',
        '_'
    ), array(
        '+',
        '/'
    ), $data);
    $mod4 = strlen($data) % 4;
    if ($mod4) {
        $data .= substr('====', $mod4);
    }
    $data = base64_decode($data);
    $expire = substr($data, 0, 10);
    $data = substr($data, 10);

    if ($expire > 0 && $expire < time()) {
        return '';
    }
    $x = 0;
    $len = strlen($data);
    $l = strlen($key);
    $char = $str = '';

    for ($i = 0; $i < $len; $i++) {
        if ($x == $l) {
            $x = 0;
        }
        $char .= substr($key, $x, 1);
        $x++;
    }

    for ($i = 0; $i < $len; $i++) {
        if (ord(substr($data, $i, 1)) < ord(substr($char, $i, 1))) {
            $str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1)));
        } else {
            $str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1)));
        }
    }
    return base64_decode($str);
  }
  public static function extractToken($token,$key=''){
    $cache_key="allen_api_extract_token_key";
    if(empty($key)){
        $key=Redis::GET($cache_key);
        if(empty($key)){
            $value=DB::connection('shop')->table('config')->where([
                'config_key'=>'API_CONFIG',
                'app_module'=>'admin'
            ])->value('value');
            $value=json_decode($value,true);
            $value=$value['private_key'];
            Redis::SET($cache_key,$value);
            $key=$value;
        }
    }
        $decrypt = self::shop_decrypt($token, $key);
        if (empty($decrypt)) return 'null decrypt';
        $data = json_decode($decrypt, true);
        if (!isset($data[ 'member_id' ]) || empty($data[ 'member_id' ])) return 'null member_id';
        return $data[ 'member_id' ];
  }
}
